﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Diagnostics;

namespace ImPM.Application
{
    public sealed class Exceptions
    {
        // Methods
        private Exceptions()
        {
        }

        public static void ThrowIfEmpty(string value, string parameterName)
        {
            ThrowIfNull(value, parameterName);
            if (value.Length == 0)
            {
                throw new ArgumentException("Expected non-empty string.", parameterName);
            }
        }

        public static void ThrowIfGuidEmpty(Guid parameter, string name)
        {
            if (parameter == Guid.Empty)
            {
                throw new ArgumentException(name);
            }
        }

        public static void ThrowIfInterfaceNotImplemented(Type type, Type interfaceInQuestion)
        {
            foreach (Type type2 in type.GetInterfaces())
            {
                if (type2 == interfaceInQuestion)
                {
                    return;
                }
            }
            throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "{0} must implement the required interface: {1}.", new object[] { type.Name, interfaceInQuestion.Name }));
        }

        public static void ThrowIfNegative(int value, string parameterName)
        {
            if (value < 0)
            {
                throw new ArgumentOutOfRangeException(parameterName, value, "Value for this parameter must be equal or greater than zero.");
            }
        }

        public static void ThrowIfNegative(TimeSpan value, string parameterName)
        {
            if (value < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(parameterName, value, "Value for this parameter must be equal or greater than zero.");
            }
        }

        [Conditional("DEBUG")]
        public static void ThrowIfNotDefined(Type enumType, object value, string parameterName)
        {
            if (!enumType.IsSubclassOf(typeof(Enum)))
            {
                throw new InvalidOperationException("Unable to perform IsDefined operation on non-enum types.");
            }
            if (!Enum.IsDefined(enumType, value))
            {
                throw new ArgumentOutOfRangeException(parameterName, value, "Value for this parameter must be defined by the enum.");
            }
        }

        public static void ThrowIfNotEmpty(string value, string parameterName)
        {
            if ((value != null) && (value.Length != 0))
            {
                throw new ArgumentException("Expected empty string.", parameterName);
            }
        }

        public static void ThrowIfNotPositive(int value, string parameterName)
        {
            if (value <= 0)
            {
                throw new ArgumentOutOfRangeException(parameterName, value, "Value for this parameter must be greater than zero.");
            }
        }

        public static void ThrowIfNull(object parameter, string name)
        {
            if (parameter == null)
            {
                throw new ArgumentNullException(name);
            }
        }

        public static void ThrowIfNullOrEmpty(string parameter, string name)
        {
            ThrowIfNull(parameter, name);
            ThrowIfEmpty(parameter, name);
        }

        public static void ThrowIfOutOfRange(int value, int min, int max, string parameterName)
        {
            if ((value < min) || (value > max))
            {
                throw new ArgumentOutOfRangeException(parameterName, value, string.Format(CultureInfo.InvariantCulture, "Expected value between {0} and {1} inclusive.", new object[] { min, max }));
            }
        }
    }


}
